/*
 *	Copyright 2011 andro-inject developers 
 *	Licensed under the Apache License, Version 2.0 (the "License"); 
 *	you may not use this file except in compliance with the License. 
 *	You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 * 
 *	Unless required by applicable law or agreed to in writing, software 
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License. 
 * 
*/

package com.androinject.core.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.FileInputStream;
import java.io.IOException;

import com.androinject.core.ComponentFactory;
import com.androinject.core.factory.xml.DefaultXmlComponentFactory;
import com.androinject.test.components.InstanceCounter;
import com.androinject.test.components.TestComponent;
import com.androinject.test.components.TestComponentA;
import com.androinject.test.components.TestComponentB;
import com.androinject.test.components.TestComponentC;

public class AiTestCase {
	
	protected ComponentFactory factory;

	protected void createFactoryFromXml(String xmlFile) throws IOException {
		this.factory = new DefaultXmlComponentFactory(new FileInputStream(xmlFile));
	}
	
	protected ComponentFactory getFactory() {
		return this.factory;
	}
	
	protected Object getComponent(String id) {
		return this.getFactory().getComponent(id);
	}
	
	protected Object getComponentOrFail(String id) {
		Object o = this.getFactory().getComponent(id);
		if (o == null) {
			fail();
		}
		return o;
	}
	
	protected <T> T getComponent(String id, Class<T> requiredClass) {
		return this.getFactory().getComponent(id, requiredClass);
	}
	
	protected <T> T getComponentOrFail(String id, Class<T> requiredClass) {
		T t = this.getFactory().getComponent(id, requiredClass);
		if (t == null) {
			fail();
		}
		return t;
	}
	
	protected Class<?> getType(String id) {
		return this.getFactory().getType(id);
	}
	
	protected void initializeManagedComponent(Object componentToInitialize) {
		this.getFactory().initializeManagedComponent(componentToInitialize);
	}
	
	protected void initializeManagedComponent(Object componentToInitialize, String id) {
		this.getFactory().initializeManagedComponent(componentToInitialize, id);
	}
	
	protected <T> void checkComponentClass(String id, Class<T> expectedClass) {
		Object component = this.factory.getComponent(id);
		T castedComponent = this.factory.getComponent(id, expectedClass);
		assertNotNull(component);
		assertNotNull(castedComponent);
		assertTrue(expectedClass.isAssignableFrom(component.getClass()));
		assertTrue(component.getClass().isAssignableFrom(expectedClass));
		assertTrue(component == castedComponent);
	}
	
	protected void checkDependencies(TestComponent component, TestComponent first, TestComponent second, TestComponent third) {
		assertEquals(first, component.getFirst());
		assertEquals(second, component.getSecond());
		assertEquals(third, component.getThird());
	}
	
	protected void resetAllGlobalInstanceCounters() {
		InstanceCounter.resetAllCounters();
	}
	
	protected void checkComponentInstances(int a, int b, int c) {
		assertEquals(a, TestComponentA.getGlobalInstanceCount());
		assertEquals(b, TestComponentB.getGlobalInstanceCount());
		assertEquals(c, TestComponentC.getGlobalInstanceCount());
	}
}
